﻿// ---------------------------------------------------------------------------------------------
// <copyright file="StronglyConnectedComponentList.cs" company="Daniel Bradley">
//   Copyright (c) 2015 All Rights Reserved
// </copyright>
// <summary>
//   cf. https://github.com/danielrbradley/CycleDetection
// </summary>
// ---------------------------------------------------------------------------------------------

using System.Collections;
using System.Collections.Generic;
using System.Linq;

namespace Hiyoko.DependenciesSorter.CycleDetection
{
    public class StronglyConnectedComponentList<T> : IEnumerable<StronglyConnectedComponent<T>>
    {
        #region Private members

        /// <summary>
        /// The collection of strongly connected components.
        /// </summary>
        private readonly LinkedList<StronglyConnectedComponent<T>> _collection;

        #endregion Private members

        #region Constructors

        /// <summary>
        /// Initializes a new instance of the StronglyConnectedComponentList class.
        /// </summary>
        public StronglyConnectedComponentList()
        {
            _collection = new LinkedList<StronglyConnectedComponent<T>>();
        }

        /// <summary>
        /// Initializes a new instance of the StronglyConnectedComponentList class.
        /// </summary>
        /// <param name="collection">The collection of strongly connected components.</param>
        public StronglyConnectedComponentList(IEnumerable<StronglyConnectedComponent<T>> collection)
        {
            _collection = new LinkedList<StronglyConnectedComponent<T>>(collection);
        }

        #endregion Constructors

        #region Properties

        /// <summary>
        /// Gets the total of strongly connected components in the colelction.
        /// </summary>
        public int Count
        {
            get
            {
                return this._collection.Count;
            }
        }

        #endregion Properties

        #region Public methods

        /// <summary>
        /// Adds a strongly connected component to the collection.
        /// </summary>
        /// <param name="scc">The strongly connected component.</param>
        public void Add(StronglyConnectedComponent<T> scc)
        {
            _collection.AddLast(scc);
        }

        public IEnumerator<StronglyConnectedComponent<T>> GetEnumerator()
        {
            return _collection.GetEnumerator();
        }

        IEnumerator IEnumerable.GetEnumerator()
        {
            return _collection.GetEnumerator();
        }

        public IEnumerable<StronglyConnectedComponent<T>> IndependentComponents()
        {
            return this.Where(c => !c.IsCycle);
        }

        public IEnumerable<StronglyConnectedComponent<T>> Cycles()
        {
            return this.Where(c => c.IsCycle);
        }

        #endregion Public methods
    }
}
